package cliente.so;

import java.rmi.RemoteException;
import java.util.List;

import javax.swing.JFrame;

import cliente.gerenciadorcliente.so.SOGerenciadorClienteEntrada;
import cliente.gerenciadorcliente.so.SOGerenciadorClienteSaida;
import cliente.jogocliente.so.SOJogoClienteEntrada;

import comum.rn.RNDescricaoSalaJogo;
import comum.rn.RNEstatisticas;
import comum.rn.RNInfoSalaJogo;
import comum.rn.RNJogada;
import comum.rn.RNPeca;
import comum.so.SOServidorEntrada;
import comum.so.SOClienteEntrada;
import comum.so.exception.FalhaComunicacaoBancoDadosException;
import comum.so.exception.FalhaValidacaoException;
import comum.so.exception.JaExistePerfilCadastradoComEsseLoginException;
import comum.so.exception.LoginEmUsoException;
import comum.so.exception.SalaCheiaException;
import comum.so.exception.SalaComNomeJaExistenteException;
import comum.so.exception.SalaNaoExisteException;
import comum.so.exception.SenhaIncorretaException;

public class SOClienteSaidaImpl implements SOClienteSaida {

	private String identificador;

	private SOServidorEntrada servidorEntrada;
	private SOGerenciadorClienteEntrada gerenciadorClienteEntrada;
	private SOGerenciadorClienteSaida gerenciadorClienteSaida;
	private SOJogoClienteEntrada jogoClienteEntrada;
	private SOClienteEntrada clienteEntrada;

	public String getIdentificador() {
		return identificador;
	}

	@Override
	public void fazerLogin(String identificador, String senha)
			throws RemoteException, FalhaValidacaoException,
			LoginEmUsoException, FalhaComunicacaoBancoDadosException {
		getServidorEntrada().fazerLogin(identificador, senha,
				getClienteEntrada());
		this.identificador = identificador;
	}

	@Override
	public void deslogar() throws RemoteException {
		getServidorEntrada().deslogar(identificador);
	}

	@Override
	public void cadastrarNovoPerfil(String identificador, String senha)
			throws RemoteException,
			JaExistePerfilCadastradoComEsseLoginException {
		getServidorEntrada().cadastrarNovoPerfil(identificador, senha,
				getClienteEntrada());
		this.identificador = identificador;
	}

	@Override
	public List<RNDescricaoSalaJogo> buscarSalasJogo(boolean mostrarCheios,
			boolean mostrarSenha) throws RemoteException {
		return getServidorEntrada()
				.buscarSalasJogo(mostrarCheios, mostrarSenha);
	}

	@Override
	public RNInfoSalaJogo entrarSalaJogo(Long idSalaJogo, String senha)
			throws RemoteException, SalaCheiaException, SalaNaoExisteException,
			SenhaIncorretaException {
		return getServidorEntrada().entrarSalaJogo(identificador, idSalaJogo,
				senha);
	}

	@Override
	public RNInfoSalaJogo criarSalaJogo(String nome, String senha)
			throws RemoteException, SalaComNomeJaExistenteException {
		return getServidorEntrada().criarSalaJogo(nome, senha, identificador);
	}

	@Override
	public RNEstatisticas obterEstatisticas() throws RemoteException {
		return getServidorEntrada().obterEstatisticas(identificador);
	}

	@Override
	public void iniciarPartida(String identificadorAdministrador,
			Long idSalaJogo) throws RemoteException {
		getServidorEntrada().iniciarPartida(idSalaJogo);

	}

	@Override
	public void sairSalaEspera(Long idSalaJogo) throws RemoteException {
		getServidorEntrada().sairSalaEspera(idSalaJogo, identificador);
	}

	@Override
	public void desistirJogo(Long idSalaJogo) throws RemoteException {
		getServidorEntrada().desistirJogo(idSalaJogo, identificador);
	}

	@Override
	public boolean entrarMesa(int posicaoDesejada, Long idSalaJogo)
			throws RemoteException {
		return getServidorEntrada().entrarMesa(posicaoDesejada, idSalaJogo,
				identificador);
	}

	@Override
	public void sairMesa(Long idSalaJogo) throws RemoteException {
		getServidorEntrada().sairMesa(idSalaJogo, identificador);
	}

	@Override
	public void fazerJogada(Long idSalaJogo, RNJogada jogada)
			throws RemoteException {
		getServidorEntrada().fazerJogada(identificador, idSalaJogo, jogada);
	}

	@Override
	public void abrirSalaPrincipal(JFrame frame) {
		getGerenciadorClienteEntrada().abrirSalaPrincipal(frame, identificador,
				getGerenciadorClienteSaida());
	}

	@Override
	public void iniciarSalaJogo(RNInfoSalaJogo infoSalaJogo, JFrame frame) {
		getJogoClienteEntrada().iniciarSalaJogo(infoSalaJogo, frame,
				identificador);
	}

	@Override
	public void informarEntradaJogador(String jogadorQueEntrou,
			RNInfoSalaJogo infoSalaJogo) throws RemoteException {
		getJogoClienteEntrada().informarEntradaJogador(jogadorQueEntrou,
				infoSalaJogo);
	}

	@Override
	public void informarSaidaJogador(String jogadorQueSaiu,
			SOControladoraClienteIU controladoraIU, RNInfoSalaJogo infoSalaJogo)
			throws RemoteException {
		getJogoClienteEntrada().informarSaidaJogador(identificador,
				jogadorQueSaiu, controladoraIU, infoSalaJogo);
	}

	@Override
	public void informarMudancaMesa(Integer[] posicoesMesa) {
		getJogoClienteEntrada().informarMudancaMesa(posicoesMesa);
	}

	@Override
	public void informarJogada(String jogadorQueJogou, RNJogada jogada,
			String novoJogadorEmTurno) {
		getJogoClienteEntrada().informarJogada(jogadorQueJogou, jogada,
				novoJogadorEmTurno);
	}

	@Override
	public void informarFimPartida(String mensagem,
			SOControladoraClienteIU controladoraIU) {
		getJogoClienteEntrada().informarFimPartida(mensagem, controladoraIU);
	}
	
	@Override
	public void informarInicioPartida(List<RNPeca> pecas, String primeiroAJogar) {
		getJogoClienteEntrada().informarInicioPartida(pecas, primeiroAJogar);
	}

	protected SOServidorEntrada getServidorEntrada() {
		return servidorEntrada;
	}

	protected SOGerenciadorClienteEntrada getGerenciadorClienteEntrada() {
		return gerenciadorClienteEntrada;
	}

	protected SOGerenciadorClienteSaida getGerenciadorClienteSaida() {
		return gerenciadorClienteSaida;
	}

	protected SOJogoClienteEntrada getJogoClienteEntrada() {
		return jogoClienteEntrada;
	}

	protected SOClienteEntrada getClienteEntrada() {
		return clienteEntrada;
	}

	public void setIdentificador(String identificador) {
		this.identificador = identificador;
	}

	public void setServidorEntrada(SOServidorEntrada servidorEntrada) {
		this.servidorEntrada = servidorEntrada;
	}

	public void setGerenciadorClienteEntrada(
			SOGerenciadorClienteEntrada gerenciadorClienteEntrada) {
		this.gerenciadorClienteEntrada = gerenciadorClienteEntrada;
	}

	public void setGerenciadorClienteSaida(
			SOGerenciadorClienteSaida gerenciadorClienteSaida) {
		this.gerenciadorClienteSaida = gerenciadorClienteSaida;
	}

	public void setJogoClienteEntrada(SOJogoClienteEntrada jogoClienteEntrada) {
		this.jogoClienteEntrada = jogoClienteEntrada;
	}

	public void setClienteEntrada(SOClienteEntrada clienteEntrada) {
		this.clienteEntrada = clienteEntrada;
	}

}
